/**
  ******************************************************************************
  * @file    backwork.h
  * @author  Dragon.Chen
  * @version V1.0.0
  * @date    09-22-2014
  * @brief   业务逻辑代码
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2014 上海今中网络科技有限公司 </center></h2>
  ******************************************************************************
  */

#ifndef __BACKWORK__H__
#define __BACKWORK__H__

#include "event.h"


#define InitSockBufferManage() \
            SockBufferManage.nSockBuffer        = 256;      /* 256为260K内存大小 */ \
            SockBufferManage.maxSockBufferList  = 32;       /* 32 */\
            SockBufferManage.nSockBufferList    = 16;       /* 16*260K */\
            init_sock_buffer(&SockBufferManage)

#define InitCertificateManage() \
            CertificateManage.nCertificate = 1024;          /* 1024为2M内存大小 */\
            init_certifcate(&CertificateManage)

#define InitClientDataManage() \
            ClientDataManage.nClientData = WORKER_MAX_NCLIENT; \
            ClientDataManage.nUsedClientData = -2;          /* 两个socketpair除外 */\
            init_client_data(&ClientDataManage)

#define SetCallback(cb, events) \
            clientData->callback = cb;  \
            modify_event(Epollfd, clientData, events, ET)   /* ET model */

///****************patched by yagamishi add*************2016/02/18**********
///******************发送日志************************************************
///*******************FinalizeOther里添加了CloseDatabase(ZDLogDbHandle)***
///*************************************************************************
#define FinalizeOther() \
            CloseDatabase(dbHandle); \
            CloseDatabase(ZDLogDbHandle); \
            free(VPNPortCount); \
            VPNPortCount = NULL; \
            X509_CRL_free(CertRevokedList); \
            CertRevokedList = NULL; \
            X509_STORE_free(RootCertStore); \
            RootCertStore = NULL

#define AdjustTimer() \
            adjust_timer(&clientData->timer, time(NULL) + WORKER_HEARTBEAT_TIMEOUT)

#define IsShutdown() \
            if (clientData->shutdown == YES) \
                goto tag_close_socket

/**
  * @brief  发送socket数据(数据量不大于1016)
  * @param  arg1:用户数据 arg:下次回调函数
  * @retval	void
  */
#define SendCommand(clientData, callback) \
            else\
            {\
                memcpy(sockBuffer, \
                       clientData->sockBuffer->buffer, \
                       clientData->sockBuffer->bufferLength);\
                sendDataSize = clientData->sockBuffer->bufferLength - \
                               clientData->sockBuffer->bufferPosition;\
                sendDataPosition = clientData->sockBuffer->bufferPosition;\
            }\
\
            while (TRUE) \
            { \
                retval = send(clientData->sockfd, sockBuffer+sendDataPosition, sendDataSize, 0); \
                if (retval < 0) \
                { \
                    if (errno == EINTR) \
                    { \
                        continue; \
                    } \
                    else if (errno == EAGAIN || errno == EWOULDBLOCK) \
                    { \
                        SetCallback((CLIENT_EVENT_T *)__FUNCTION__, EPOLLOUT); \
                        return RETURN_SUCCESS; \
                    } \
                    else \
                    { \
                        goto tag_close_socket; \
                    } \
                }\
                else if (retval == 0) \
                { \
                    goto tag_close_socket; \
                } \
\
                sendDataSize -=retval; \
                if (sendDataSize == 0) \
                { \
                    if (clientData->sockBuffer != NULL) \
                    { \
                        free_sock_buffer(&SockBufferManage, clientData->sockBuffer); \
                        clientData->sockBuffer = NULL; \
                    } \
                    break;\
                } \
                else if (sendDataSize > 0) \
                { \
                    if (clientData->sockBuffer == NULL) \
                    { \
                        clientData->sockBuffer = get_sock_buffer(&SockBufferManage); \
                        if (clientData->sockBuffer == NULL) \
                            goto tag_close_socket; \
\
                        clientData->sockBuffer->bufferLength = sendDataSize + retval; \
                        memcpy(clientData->sockBuffer->buffer, sockBuffer, \
                               clientData->sockBuffer->bufferLength); \
                    } \
                    clientData->sockBuffer->bufferPosition += retval;\
                    sendDataPosition += retval;\
                } \
                else \
                { \
                    goto tag_close_socket; \
                } \
            } \
\
            SetCallback(callback, EPOLLIN); \
            return RETURN_SUCCESS; \
\
tag_close_socket : \
            close_socket(clientData, EVENT_OF_CLIENT); \
            return RETURN_FAILURE

/**
  * @brief  master进程定时器超时处理
  * @param  void
  * @retval void
  */
void master_timer_timeout();

/**
  * @brief  worker进程定时器超时处理无效socket
  * @param  void
  * @retval void
  */
void worker_timer_timeout();

/**
  * @brief  迫使用户下线(数据格式:arg1;aa;bb;cc;)
  * @param  void
  * @retval void
  */
void worker_remove_client();

/**
  * @brief  重读服务器配置文件
  * @param  void
  * @retval void
  */
void worker_reread_config();

/**
  * @brief  重新载入CA
  * @param  void
  * @retval void
  */
void worker_reload_ca();

/**
  * @brief  重新载入CRL
  * @param  void
  * @retval void
  */
void worker_read_crl();

/******************************* Worker进程接收客户请求发送响应 *******************************/
/**
  * @brief  关闭socket
  * @param  arg1:用户数据   arg2:event
  * @retval NULL
  */
void close_socket(CLIENT_DATA_T *clientData, int event);

/**
  * @brief  接收客户欢迎请求
  * @param  arg1:用户数据
  * @retval RETURN_SUCCESS
  */
int recv_welcome_request_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送客户欢迎请求
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_welcome_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  从客户端接收数据并且解析头部
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int recv_requests_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送登录响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_version_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送X509响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int recv_requests_of_x509_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送X509响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_x509_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送SN响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_sn_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送bind响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_bind_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送apptype响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_apptype_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送openvpn响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_openvpn_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送stunnel响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_stunnel_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送utunnel响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_utunnel_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送hearbeat时间间隔响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_heartbeat_timeout_response_cb(CLIENT_DATA_T *clientData);

/**
  * @brief  发送hearbeat响应
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS, 否则RETURN_FAILURE
  */
int send_heartbeat_response_cb(CLIENT_DATA_T *clientData);


#endif


/******************* (C) COPYRIGHT 2014 上海今中网络科技有限公司 *****END OF FILE****/


